/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.chain.presenter;

import br.com.chain.programa.TratadorProgram;
import br.com.colecoes.TabelaDeSimbolos;
import br.com.model.Token;
import java.util.ArrayList;
import javax.swing.JTextArea;

/**
 *
 * @author Bush
 */
public class AnalisadorLexico {

    private JTextArea areaTexto;
    private ArrayList<Token> tabelaDeSimbolosSaida;
    private ArrayList<String> erros;
    private static AnalisadorLexico instancia;

    private AnalisadorLexico() {        
    }
    
    public void setJTextArea(JTextArea areaTexto) {
        this.areaTexto = areaTexto;
    }
    public static AnalisadorLexico getInstancia(){
        if(instancia == null)
            instancia = new AnalisadorLexico();
        return instancia;
    }

    public void analiseLexica() {
        int id = 0;
        tabelaDeSimbolosSaida = new ArrayList<>();
        erros = new ArrayList<>();
        String codigo = areaTexto.getText();
        codigo = replaceCodigoFonte(codigo);
        String linhas[] = codigo.split("\n");

        for (int i = 0; i < linhas.length; i++) {
            String linha[] = linhas[i].split("\\s");

            for (int j = 0; j < linha.length; j++) {
                if(linha[j].equals("###"))
                    break;
                Token token = new Token(id + 1, i + 1, linha[j], "");
                id++;
                tabelaDeSimbolosSaida.add(token);
            }
            int tam = tabelaDeSimbolosSaida.size();
            TabelaDeSimbolos.getIntancia().restauraTabelaSimbolos();
            for (int k = 0; k < tam; k++) {
                TratadorProgram tratador = new TratadorProgram();
                if (tabelaDeSimbolosSaida.get(k).getLexema().equals("##")) {
                    excluirComentarios(k, tam);
                }
                if (tabelaDeSimbolosSaida.get(k).getLexema().trim().equals("")) {
                    tabelaDeSimbolosSaida.remove(k);
                    k--;
                    tam--;
                } else {
                    tratador.tratador(tabelaDeSimbolosSaida.get(k));    // Aqui é verificado se o lexima é valido
                    String lexema = tabelaDeSimbolosSaida.get(k).getLexema();
                    String token = tabelaDeSimbolosSaida.get(k).getToken();
                    TabelaDeSimbolos.getIntancia().adicionaToken(lexema, token);
                    //Possível Chamada do Analisador sintático chamadaFuncao(tabelaSimbolosSaida,0,erros);
                }
            }
            tam = tabelaDeSimbolosSaida.size();
            for (int k = 0; k < tam; k++) {
                String lexema = tabelaDeSimbolosSaida.get(k).getLexema();
                int ID = TabelaDeSimbolos.getIntancia().getIdLexema(lexema);
                tabelaDeSimbolosSaida.get(k).setId(ID);
            }
        }

    }

    public void excluirComentarios(int pos, int tam) {
            tabelaDeSimbolosSaida.get(pos).setLexema("");
            tam--;
            for (int k = pos; k < tam; k++) {
                tabelaDeSimbolosSaida.get(k).setLexema("");
                if (tabelaDeSimbolosSaida.get(k).getLexema().equals("##")) {
                    tabelaDeSimbolosSaida.get(k).setLexema("");
                    tam--;
                    break;
                }
            }
    }
    
    

    public String replaceCodigoFonte(String codigo) {
        codigo = codigo.replaceAll("//", " ### ");
        codigo = codigo.replace("{", " ## ");
        codigo = codigo.replace("}", " ## ");
        codigo = codigo.replace("(*", " ## ");
        codigo = codigo.replace("*)", " ## ");
        codigo = codigo.replaceAll("\t", ""); //retira tab
        codigo = codigo.replaceAll(";", " ; ");
        codigo = codigo.replaceAll("end", "end ");
        codigo = codigo.replaceAll(",", " , ");
        codigo = codigo.replace("(", " ( ");
        codigo = codigo.replace(")", " ) ");
        codigo = codigo.replace("[", " [ ");
        codigo = codigo.replace("]", " ] ");
        codigo = codigo.replace("+", " + ");
        codigo = codigo.replace("-", " - ");
        codigo = codigo.replace("/", " / ");
        codigo = codigo.replace("*", " * ");
        codigo = codigo.replace(":=", " := ");
        return codigo;
    }

    public ArrayList<Token> getTabelaDeSibolos() {
        return tabelaDeSimbolosSaida;
    }

}
